package com.cl.service.payGrant;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Writer;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.SimpleFormatter;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;

import net.sf.jxls.transformer.XLSTransformer;

import org.apache.commons.lang.ObjectUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cl.dao.CommonDao;
import com.cl.dao.SearchDao;
import com.cl.dto.PayDTO;
import com.cl.entity.CcPay;
import com.cl.entity.CcPayHistory;
import com.cl.entity.UUser;
import com.cl.service.FileService;
import com.cl.util.CommonUtil;
import com.sun.istack.internal.logging.Logger;

@Service
public class PayGrantExcelService {
	
	public static final int PAY_COUNT_MAX = 30000;

	@Value("#{applicationProperties['PAY_EXCEL_PATH']}")
	private String outPath;
	
	@Value("#{applicationProperties['PAY_EXCEL_TEMPLATE_FILE']}")
	private String templateFile;

	@Autowired
	private CommonDao commonDao;
	
	@Autowired
    private FileService fileService;

	@Autowired
	private DataGenerator dg;

	@Autowired
	private CommonUtil commonUtil;

	@Autowired
	private SearchDao searchDao;
	
	@PersistenceContext(unitName = "entityManagerFactory")
	private EntityManager entityManager;
	
	@Value("#{applicationProperties['SECRETARY']}")
	private String secretary;
	
	//c4w 具体逻辑应放在业务service中，方便进行事务配置
	@SuppressWarnings("unchecked")
	@Transactional
	public PayDTO generateExcel(HttpServletRequest request, String zfpd_id,String bgTM,
			 String endTM,boolean bPreview) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
		List<CcPay> ccPayList = searchDao.getPayGrantsList(sdf.parse(bgTM), sdf.parse(endTM));	
		String str1="";	
		int cout_input = ccPayList.size();
		int cout_null=0;
		String ip = commonUtil.getIpAddress(request);
		String userId = commonUtil.getCurrentUserID();
		ObjectMapper objectMapper = new ObjectMapper();
		//j 采购执行人
		Subject subject = SecurityUtils.getSubject();
        UUser user = (UUser) subject.getPrincipal();
        String cgzxrname =user.getName();
        String cgzxrcn=user.getUserId();
		String cgzxr="resource:"+cgzxrcn+":"+cgzxrname;
	   // List<UUser> orguser = searchDao.getorguser(objpay.getAuthorId());
		List<UUser> orguser = searchDao.listOrgUsers("资料信息部",1000);
		Iterator it = ccPayList.iterator();
		int cout_merge=0;
		
		//c4w 3.31 增加稿酬总钱数
		int reward_total = 0;
		int  reward_org=0;
		//j 接口数据 s
		List<Map<String,Object>> s = new ArrayList<Map<String,Object>>();
		while (it.hasNext()) {
			CcPay c = (CcPay) it.next();
			//c.setReGiveFlag("Y");
			entityManager.detach(c);
			/*if(c.getRewardCMan()!=null){
				 String dt0 =c.getRewardCMan();
				 s.add(dt0);
			}*/
			if(c.getAuthorId()!=null){
				String orignal=c.getAuthorId();
				//List<UOrg> orglst = searchDao.getAllUOrgs(c.getAuthorId());
					//person
				HashMap hashmap =new HashMap();
				if(orignal.indexOf(';')!=-1){
					String[] orignal1=orignal.split(";");
					 for(int i=0;i<orignal1.length;i++){
						 String orignal2=orignal1[i];
						 if(orignal2.indexOf('[')!=-1){
							  //有[  为 person
								String username =orignal2.substring(0, orignal2.indexOf('['));
								hashmap.put("username",username);
								
								if(orignal2.indexOf(',')!=-1){
									String cn =c.getAuthorId().substring(orignal2.indexOf('[')+1,orignal2.indexOf(','));
									hashmap.put("userid",cn);
									if(orignal2.indexOf("cn")>-1){
										int ynflag=1;
										hashmap.put("ynflag",ynflag);
									}else{
										int ynflag=0;
										hashmap.put("ynflag",ynflag);
									}	
								}else{
									String cn =c.getAuthorId().substring(orignal2.indexOf('[')+1,orignal2.indexOf(']'));
									hashmap.put("userid",cn);
									if(orignal2.indexOf("cn")>-1){
										int ynflag=1;
										hashmap.put("ynflag",ynflag);
									}else{
										int ynflag=0;
										hashmap.put("ynflag",ynflag);
									}
								}
								//j 增加null判断
								if(c.getReward()!=null){
									//j 多个当事人 稿费平均
									 double ldbcje = c.getReward().divide(BigDecimal.valueOf(orignal1.length), 0, BigDecimal.ROUND_DOWN).doubleValue();
//								double ldbcje =c.getReward().doubleValue();
								hashmap.put("ldbcje",ldbcje);
								}else{
									double ldbcje=0.0;
									hashmap.put("ldbcje",ldbcje);
								}
								
						 }else{
							 //无[
							 String username =orignal2;
							 if(!username.equals("资料信息部")&&!username.equals("资料信息中心")){
								     //person
								     hashmap.put("username",username);
								     int userid=0;
								     hashmap.put("userid",userid);
								     int ynflag=0;
								     hashmap.put("ynflag",ynflag);
								   //j 增加null判断
										if(c.getReward()!=null){
										double ldbcje =c.getReward().doubleValue();
										hashmap.put("ldbcje",ldbcje);
										}else{
											double ldbcje=0.0;
											hashmap.put("ldbcje",ldbcje);
										}
									}else{
										//org
										reward_org += c.getReward().intValue();
									}							
						 }
					 }
					
				}else{
					if(orignal.indexOf('[')!=-1){
						//有[  为 person
						String username =orignal.substring(0, orignal.indexOf('['));
						hashmap.put("username",username);
						
						if(orignal.indexOf(',')!=-1){
							String cn =c.getAuthorId().substring(orignal.indexOf('[')+1,orignal.indexOf(','));
							hashmap.put("userid",cn);
							if(orignal.indexOf("cn")>-1){
								int ynflag=1;
								hashmap.put("ynflag",ynflag);
							}else{
								int ynflag=0;
								hashmap.put("ynflag",ynflag);
							}
							//j 增加null判断
							if(c.getReward()!=null){
							double ldbcje =c.getReward().doubleValue();
							hashmap.put("ldbcje",ldbcje);
							}else{
								double ldbcje=0.0;
								hashmap.put("ldbcje",ldbcje);
							}	
						}else{
							String cn =c.getAuthorId().substring(orignal.indexOf('[')+1,orignal.indexOf(']'));
							hashmap.put("userid",cn);
							if(orignal.indexOf("cn")>-1){
								int ynflag=1;
								hashmap.put("ynflag",ynflag);
							}else{
								int ynflag=0;
								hashmap.put("ynflag",ynflag);
							}
							//j 增加null判断
							if(c.getReward()!=null){
							double ldbcje =c.getReward().doubleValue();
							hashmap.put("ldbcje",ldbcje);
							}else{
								double ldbcje=0.0;
								hashmap.put("ldbcje",ldbcje);
							}
						}
						
						}else{
							 //无[
							 String username =orignal;
							 if(!username.equals("资料信息部")&&!username.equals("资料信息中心")){
								     //person
								     hashmap.put("username",username);
								     int userid=0;
								     hashmap.put("userid",userid);
								     int ynflag=0;
								     hashmap.put("ynflag",ynflag);
								   //j 增加null判断
										if(c.getReward()!=null){
										double ldbcje =c.getReward().doubleValue();
										hashmap.put("ldbcje",ldbcje);
										}else{
											double ldbcje=0.0;
											hashmap.put("ldbcje",ldbcje);
										}
									}else{
										//org
										reward_org += c.getReward().intValue();
									}						
						}
				}

					if(!hashmap.isEmpty()){
						s.add(hashmap);
					}

		 
			}else{
				it.remove();
			}
			
			
			if(c.getDocNumber()==null){
				c.setDocNumber(BigDecimal.ZERO);
			}
			if (c.getReward()==null || c.getReward().intValue() == 0) {
				it.remove();
				cout_null++;
				int dt1=cout_null;
			}else{
				reward_total += c.getReward().intValue();
			}	
		}	
	
		//org
		 BigDecimal bd = BigDecimal.valueOf(reward_org);
		 double ldbcje = bd.divide(BigDecimal.valueOf(orguser.size()), 0, BigDecimal.ROUND_DOWN).doubleValue();
		 for (Iterator<UUser> iter = orguser.iterator(); iter.hasNext();) {
			 HashMap hashmap1 =new HashMap();
			 UUser org= (UUser)iter.next();
			 String username =org.getName();
			 //String userid = org.getUserId();
			 String userid =org.getUserId().substring(org.getUserId().indexOf('[')+1,org.getUserId().length());
			 hashmap1.put("username",username);
			 hashmap1.put("userid",userid);
			 int ynflag=1;
			 hashmap1.put("ynflag",ynflag);
			 hashmap1.put("ldbcje",ldbcje);
			 s.add(hashmap1);
		}
			//0714jj  增加查重判断，相同name,金额累加	
			ArrayList s1 = new ArrayList();
			Map<String,Map<String,Object>> map = new HashMap<String,Map<String,Object>>();
				 for (Map<String,Object> m1 : s)  
				    {  
				     String key=(String) m1.get("username");
				     System.out.println("lllllllllllll:"+m1.get("ldbcje"));
				     if(map.containsKey(key)){
				    	 Map<String,Object> m2 = map.get(key);
				    	 //金额累加
				    	 double val1 = Double.parseDouble(m1.get("ldbcje")+"");
				    	 double val2 = Double.parseDouble(m2.get("ldbcje")+"");			    	 
				    	 String val=Double.toString(val1+val2);
				    	 m2.put("ldbcje",val);				    	 
				    	 map.remove(key);				    	 
				    	 map.put(key, m2);
				     }else{
					     map.put(key, m1);
				     }
				    }
				   //取出value放到s1
				 for(Entry<java.lang.String, Map<java.lang.String, Object>> entry: map.entrySet()) {
					 s1.add(entry.getValue());
					}
				 System.out.println("ppppppppppppppppppppppppp:"+s1);
        int total=s1.size();
        
		if(!bPreview){
			//为提高性能，直接保存，不记录业务上不需要的人工操作日志
			/*
			entityManager.merge(c);
			cout_merge++;
			if(cout_merge>50){
				entityManager.flush();
				entityManager.clear();
			}*/
			//TODO	
//			queryKeyinElecPolicyService(s1,cgzxr,zfpd_id,total);
//			str1=queryKeyinElecPolicyService(s1,cgzxr,zfpd_id,total);
			commonDao.updatePayGive(ccPayList, "Y", userId, new Date(), ip, sdf.parse(bgTM), sdf.parse(endTM));
		}
		else{
//			str1=queryKeyinElecPolicyService(s,cgzxr,zfpd_id,total);
			commonDao.updatePayGive(ccPayList, "N", userId, new Date(), ip, sdf.parse(bgTM), sdf.parse(endTM));
		}
		int cout_output = ccPayList.size();
		//j 接口返回数据加入到ccpayList
	    String[] stsz=str1.split(";");
	    for(int i=1;i<stsz.length;i++){
	    	String stsz1=stsz[i];
	    	String[] stsz2=stsz1.split(":");
	    	CcPay ccpay=new CcPay();
	    	//ccpay.setAuthorId(stsz2[0]+stsz2[1]);
	    	ccpay.setAuthorId(stsz2[0]);
	    	 int o1=stsz2[1].indexOf('=')+1;
			 int o2=stsz2[1].length();
			 String stsz3 =stsz2[1].substring(o1,o2);
			 BigDecimal a=new BigDecimal(stsz3);
			 ccpay.setReward(a);
			 ccpay.setSubtype(stsz2[0]);
			// System.out.println(a);
	    	//ccpay.setReward(new BigDecimal(Integer.parseInt(stsz3.trim())));
//	    	ccpay.setReward(new BigDecimal(stsz2[1]));
	    	ccPayList.add(ccpay);
	    }
		//int cout_output = ccPayList.size();
		CcPayHistory cph = new CcPayHistory();
		cph.setBeginTm(sdf.parse(bgTM));
		cph.setEndTm(sdf.parse(endTM));
		cph.setConfirmMan(userId);
		commonDao.saveDBOject(cph, objectMapper.writeValueAsString(cph), userId, ip);
		String path = jxlsDemo(ccPayList, bgTM, endTM, cph);
		cph.setPath(path);
		commonDao.saveDBOject(cph, objectMapper.writeValueAsString(cph), userId, ip);
		System.out.println("jjjjjj"+reward_total);
		return new PayDTO(true,false,path,cout_input,cout_null,cout_output,cph.getId(), reward_total);
		
	}
	


	private java.lang.String substr(java.lang.String orignal, int i,
			Object instr) {
		// TODO Auto-generated method stub
		return null;
	}


	private Object instr(java.lang.String orignal, char c) {
		// TODO Auto-generated method stub
		return null;
	}


	private String String(byte[] bytes, String string) {
		// TODO Auto-generated method stub
		return null;
	}


	/**
	 * jj4.25  稿酬发放
	 * @param cgzxr 
	 *  
	 */ 
	
	@RequestMapping(value = "/api/payData")    
	 @ResponseBody  //加入响应返回数据  
	public String  queryKeyinElecPolicyService(List<String> s, String cgzxr,String zfpd_id,int total) throws IOException {    
	       //获取前台传入的参数  
          // String jsonstr = request.getParameter("jsonstr");  
	       //调用的测试接口  
//	       String url = "http://192.168.0.104/avens/finance/finance_ldbc/setLdbcServlet"; 
//	       String url = "http://192.168.1.234/avens/finance/finance_ldbc/setLdbcServlet"; 
		 //String url = "http://192.168.1.228:8888/avens/finance/finance_ldbc/setLdbcServlet"; 
//		  String url = "http://oabak.dpm.org.cn/avens/finance/finance_ldbc/setLdbcServlet";
	       //调用的正式接口  
	        String url = "http://oa.dpm.org.cn/avens/finance/finance_ldbc/setLdbcServlet"; 
	       //组装成Map 进行参数的传递  
	       Map<String,Object> params = new HashMap<String,Object>();  
	       params.put("ldbcdata", s);
	       params.put("cgzxr", cgzxr);
	       params.put("zfpd_id", zfpd_id);
	       params.put("total", total);
	       params.put("sy_yn", "网站稿酬");
	       params.put("sy_yw", "网站稿酬");
	       
	       //调用Http post 请求  
	       String resultStr = httpPost(url, params);  
	       return resultStr;
	    } 

	/**
	 * 发送Http协议 通过post传参数到接口并返回数据 
	 *  
	 */
   public static String httpPost(String urlStr,Map<String,Object> params){  
	    String s= "";		
//		String httpUrl=urlStr;
		try{
//
//			/***写内容到输出流中*/
    	    ObjectMapper objectMapper = new ObjectMapper();
    	    String jsonstr = objectMapper.writeValueAsString(params);		
//	    try{
    	    //测试接口
//    	    String url = "http://192.168.0.104/avens/finance/finance_ldbc/setLdbcServlet"; 
//    	    String url = "http://192.168.1.234/avens/finance/finance_ldbc/setLdbcServlet"; 
//    	    String url = "http://oabak.dpm.org.cn/avens/finance/finance_ldbc/setLdbcServlet";
    	    //正式接口
	    	String url = "http://oa.dpm.org.cn/avens/finance/finance_ldbc/setLdbcServlet";;
			if (url==null || "".equals(url))
			{
				System.err.println("连接oa系统时错误：wsdl尚未配置");
			}
			URL u = new URL(url);
			//String s=null;
			String t = null;
			BufferedReader r = null;String content ="";
			try {
				HttpURLConnection connection = (HttpURLConnection) u .openConnection();  
				connection.setDoOutput(true);  
				connection.setDoInput(true);  
				connection.setRequestMethod("POST");  
				connection.setUseCaches(false);  
				connection.setInstanceFollowRedirects(true);  
				connection.setRequestProperty("Content-Type",  "application/x-www-form-urlencoded");  
//				connection.setChunkedStreamingMode(5);  
				connection.connect();  
				DataOutputStream out = new DataOutputStream(connection.getOutputStream());  
   			    content =URLEncoder.encode(URLEncoder.encode(jsonstr,"utf-8"),"utf-8");
//				content ="1234";
				System.out.println("*****************************"+content.length());
				out.write("ccdata=".getBytes());
				out.write(content.getBytes());
				
				out.flush();  
				out.close(); 
				try {
					r = new BufferedReader(new InputStreamReader(connection.getInputStream()));
				} catch ( Exception ex ) {
					System.out.println("连接oa系统时错误：读流出错："+ex);
				}
				String line;
				StringBuffer buf = new StringBuffer();
				while ((line = r.readLine()) != null)
					buf.append(line);
				r.close();
				s = buf.toString();
				s = new String(s.getBytes(), "utf-8"); 
				s  = java.net.URLDecoder.decode(s.toString(),"utf-8");
				System.out.println("ssssssssssssssss:"+s);
				logRead(s);
				
			} catch ( Exception ex1 ) {
				System.out.println("连接oa系统时错误：读流出错："+ex1);
			}	
		}catch(Exception e){}
   
	    return s;	       
	 }
   
	private static void logMsg(java.lang.String logfile, java.lang.String s) {
		// TODO Auto-generated method stub
		
	}



	@SuppressWarnings({ "rawtypes", "unchecked" })
	public String jxlsDemo(List payList, String bgTM, String endTM, CcPayHistory cph) throws Exception {
		String gcExcelPath = "";
		//应依靠事务回滚而不是在catch中手工回退
		String templatefile = PayGrantExcelService.class.getResource(templateFile).getPath();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
		String subfix = templatefile.substring(templatefile.lastIndexOf(".") + 1);
		Path destPath = Paths.get(sdf.format(new Date()))
				.resolve("CC_Pay_Histroy_Excel_ID(" + cph.getId().toString() + ")"+"." + subfix);
		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA);
		Map<String, Object> beanParams = new HashMap<String, Object>();
		String outputPath = fileService.getPathWork()+File.separator+outPath+File.separator;
		Path tmpPath = Paths.get(outputPath).resolve(destPath);
		if (Files.notExists(tmpPath.getParent())) {
			Files.createDirectories(tmpPath.getParent());
		}
		gcExcelPath = tmpPath.toAbsolutePath().toString();
		//String st3 = queryKeyinElecPolicyService(s, st1,  st2,  i1);
		
		beanParams = dg.generateGroupData(payList);
		String timeInfo = sdf2.format(sdf.parse(bgTM)) + "--" + sdf2.format(sdf.parse(endTM));
		beanParams.put("timeInfo", timeInfo);
		List pdPayList = DataGenerator.generatePersonDetailData(payList);
		beanParams.put("vms", pdPayList);
		//beanParams.put("rdata", strReturn);
		XLSTransformer transformer = new XLSTransformer();
		transformer.transformXLS(templatefile, beanParams, gcExcelPath);
		return destPath.toString();
	}
		
	//添加返回数据log文件  jj 0705
      public static void logRead(String args) {
                FileOutputStream fop = null;
                File file;
                String content = args;

                try {
                     //测试路径
//                        file = new File("H:/work/logread");
                        //正式路径
                        file = new File("D:/dc/log/logread");
                        fop = new FileOutputStream(file);

                        // if file doesnt exists, then create it
                        if (!file.exists()) {
                                file.createNewFile();
                        }

                        // get the content in bytes
                        byte[] contentInBytes = content.getBytes();

                        fop.write(contentInBytes);
                        fop.flush();
                        fop.close();

                        System.out.println("Done");

                } catch (IOException e) {
                        e.printStackTrace();
                } finally {
                        try {
                                if (fop != null) {
                                        fop.close();
                                }
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                }
        }


}
